!function($){
    var Upload = function(e, t) {
        this.opts = $.extend({},
        {
            action: "",
            inputName: 'xfile',
            params: {},
            multiple: !0,
            maxConnections: 1,
            allowedExtensions: [],
            sizeLimit: 0,
            minSizeLimit: 0,
            beforeUpload: function(e) {},
            onProgress: function(e, t, n) {},
            onSuccess: function(e, t) {},
            onComplete: function(e, t) {},
            onCancel: function(e) {},
            onValidate: function(e, t) {
                return ! 0
            },
            onError: function(e, t) {}
        },
        t),
        //console.log('上传文件信息',e);
        this._queue = [],
        this._files = [],
        this._params = [],
        this._loaded = [],
        this._xhrs = [],
        this._elem = $(e),
        this._input = null,
        this._createUploadButton(),
        this._filesInProgress = 0,
        this._preventLeaveInProgress()
    };
    $.extend(Upload.prototype, {
        getTotalUpload: function(){
          var num = 0;
        },
        setParams: function() {
            this.opts.params = params
        },
        getInProgress: function() {
            return this._filesInProgress
        },
        uploadFile: function(e) {
            this._supportHTML5 && this._uploadFileList([e])
        },
        cancel: function(e) {
            if (!e) return;
            //console.log(this._files);
            var t = this._files[e];
            this.opts.onCancel(t),
            this._supportHTML5 ? (t = null, this._xhrs[e] && (this._xhrs[e].abort(), this._xhrs[e] = null)) : (delete t, $("#upload-iframe-" + e).attr("src", "javascript:false;").remove(), this._filesInProgress--, this.opts.onComplete())
        },
        _preventLeaveInProgress: function() {
            var e = this;
            $(window).bind("beforeunload", 
            function(t) {
                if (e._filesInProgress <= 0) return;
                return t.originalEvent.returnValue = "正在上传文件，如果离开上传会自动取消",
                "正在上传文件，如果离开上传会自动取消"
            })
        },
        _createUploadButton: function() {
            return this._elem.css({
                position: "relative",
                overflow: "hidden",
                direction: "ltr"
            }),
            this._elem.is("input[type=file]") || (this._input = $("<input />", {
                multiple: this.opts.multiple && this._supportHTML5,
                type: "file",
                title: "添加附件",
                name: this.opts.inputName,
                tabIndex: -1,
                css: {
                    position: "absolute",
                    right: 0,
                    top: 0,
                    fontFamily: "Arial",
                    fontSize: "118px",
                    margin: 0,
                    padding: 0,
                    cursor: "pointer",
                    opacity: 0,
                    width:"100%",
                    height:"100%",
                    overflow:'hidden'
                }
            }).on("change", $.proxy(this._onInputChange, this)), this._elem.append(this._input), window.attach && this._input.prop("tabindex", "-1")),
            this._input
        },
        _onInputChange: function() {
            this._supportHTML5 ? this._uploadFileList(this._input[0].files) : this._validateFile(this._input[0]) ? this._uploadFile(this._input[0]) : this.opts.onComplete(this._input[0]),
            this._resetUploadButton()
        },
        _resetUploadButton: function() {
            this._input[0].parentNode && this._input.remove(),
            this._input = this._createUploadButton()
        },
        _uploadFileList: function(e) {
            for (var t = 0, n = e.length; t < n; t++) if (!this._validateFile(e[t])) {
                this.opts.onComplete(e[t]);
                return
            }
            for (var t = 0, n = e.length; t < n; t++) this._uploadFile(e[t])
        },
        _uploadFile: function(e) {
          //console.log('上传文件信息', e);
            var t = this._addFile(e);
            //console.log('t',t);
            //因为截图保存到服务器端的名称为blob所以要自己传一个文件名过去到服务器端处理
            var send_params;
            if (e.snapshot){
              send_params = $.extend({}, this.opts.params, {'snapshot_name':e.name});
            } else {
              send_params = this.opts.params;
            }
            this.opts.beforeUpload(t) !== !1 && (this._filesInProgress++, this._prepareUpload(t, send_params));
        },
        _prepareUpload: function(e, t) {
            var n = this._queue.push(e.id);
            this._params[e.id] = $.extend({},
            t),
            n <= this.opts.maxConnections && this._upload(e, this._params[e.id])
        },
        _upload: function(e, t) {
            this._supportHTML5 ? this._xhrUpload(e, t) : this._formUpload(e, t)
        },
        _xhrUpload: function(e, t) {
            this._loaded[e.id] = 0;
            var n = this;
            t = t || {};
            var r = new FormData;
            r.append("authenticity_token", $('meta[name="csrf-token"]').attr("content")),
            r.append(this.opts.inputName, e.obj),
            t.original_filename = this._getFileName(e),
            $.each(t, 
            function(e, t) {
                r.append(e, t)
            });
            var i = this._xhrs[e.id] = $.ajax({
                url: this.opts.action,
                data: r,
                processData: !1,
                contentType: !1,
                type: "POST",
                headers: {
                    "X-File-Name": encodeURIComponent(e.name)
                },
                xhr: function() {
                    var e = $.ajaxSettings.xhr();
                    return e && (e.upload.onprogress = $.proxy(function(e) {
                        this.progress(e)
                    },
                    this)),
                    e
                },
                progress: function(t) {
                    t.lengthComputable && (n._loaded[e.id] = t.loaded, n.opts.onProgress(e, t.loaded, t.total))
                },
                error: function(t, r, i) {
                    n.opts.onError(e, t)
                },
                success: $.proxy(function(t) {
                    this.opts.onProgress(e, e.size, e.size),
                    this.opts.onSuccess(e, t)
                },
                this),
                complete: $.proxy(function(t, n) {
                    this._filesInProgress--,
                    this.opts.onComplete(e, $.parseJSON(t.responseText)),
                    this._files[e.id] = null,
                    this._xhrs[e.id] = null,
                    this._dequeue(e)
                },
                this)
            })
        },
        _dequeue: function(e) {
          //alert('this._queue数组长度');
          //alert(this._queue.length);
            var t = $.inArray(e.id, this._queue);
            this._queue.splice(t, 1);
            var n = this.opts.maxConnections;
            if (this._queue.length >= n && t < n) {
              //alert('开始下一个上传');
                var r = this._queue[n - 1];
                this._upload(this._files[r], this._params[r])
            }
        },
        _formUpload: function(e, t) {
            var n = e.obj;
            if (!n) throw new Error("file with does not exsit, or already uploaded or cancel");
            if($.browser.msie&&($.browser.version == "7.0")){
              //alert('找页面中的iframe');
              var r = $('#upload-iframe-general')[0];
            } else {
              var r = this._createIframe("upload-iframe-" + e.id);
            }
            //alert(r.name);
            i = this._createForm(r, t);
            i.appendChild(n);
            var s = this;
            this._attachLoadEvent(r, 
            function() {
                var t = s._getIframeContentJSON(r);
                s._filesInProgress--;
                t&& s.opts.onSuccess(e, t);
                s.opts.onComplete(e, t);
                s._files[e.id] = null;
                s._dequeue(e);
                //IE7保留iframe
                if(!($.browser.msie&&($.browser.version == "7.0"))){
                  //alert('删除iframe');
                  $(r).remove();
                } 
            });
            /*
            //ie7保留form
            if(!($.browser.msie&&($.browser.version == "7.0"))){
              alert('删除form');
              $(i).remove();
            }
            */
            i.submit();
            $(i).remove();
            return e.id;
        },
        _attachLoadEvent: function(e, t) {
          //on 改为 one  只加载一次
            $(e).one("load", 
            function() {
                if (!e.parentNode) return;
                if (e.contentDocument && e.contentDocument.body && e.contentDocument.body.innerHTML == "false") return;
                t()
            })
        },
        _getIframeContentJSON: function(iframe) {
          /*
            var doc = iframe.contentDocument;
            var response;
            alert(doc);
            
            try {
              alert(doc.body.innerHTML);
                response = eval("(" + doc.body.innerHTML + ")")
                alert(response.toString());
            } catch(err) {
              alert('返回内容为空');
                response = {}
            }
            */
            var responseHTML = $(iframe).contents().find('body').html();
            //alert('返回内容');
            //alert(responseHTML);
            $(iframe).contents().find('body').html('');
            //response = $.parseJSON(responseHTML);
            return responseHTML
        },
        _createIframe: function(e) {
            var t = $("<iframe />", {
                src: "javascript:false;",
                name: e,
                id: e,
                css: {
                    display: "none"
                }
            });
            return $(document.body).append(t),
            t[0]
        },
        _createForm: function(e, t) {
          /*
            var created = $('form[target=upload-iframe-general]');
            alert('是否找到创建的表单');
            alert(created.length);
            if(created.length > 0){
              alert('已经创建返回已有form');
              return created[0];
            }
            */
            //alert('创建 新表单'+e.name);
            var n = $('<form method="post" enctype="multipart/form-data" style="display:none"></form>');
            n.attr("action", this.opts.action).attr("target", e.name).hide();
            var r = $("meta[name=csrf-token]").attr("content"),
            i = $("meta[name=csrf-param]").attr("content");
            if (i !== undefined && r !== undefined) {
                var s = $('<input name="' + i + '" value="' + r + '" type="hidden" />');
                n.append(s)
            }
            return $.each(t, 
            function(e, t) {
                n.append('<input type="hidden" name="' + e + '" value="' + t + '" />')
            }),
            $(document.body).append(n),
            n[0]
        },
        _validateFile: function(e) {
            var t = this._getFileExtension(e);
            return this.opts.onValidate(e, t)
        },
        _addFile: function(e) {
            var t = {
                id: this._getUniqueId(),
                name: this._getFileName(e),
                size: this._getFileSize(e),
                extension: this._getFileExtension(e),
                obj: e
            };
            this._files.push(t);
            if(!this._supportHTML5){
              $(e).prop("name", this.opts.inputName);
              if(e.parentNode){
                $(e).remove();
              }
            }
            return t;
        },
        _getUniqueId: function() {
            var e = 0;
            return function() {
                return e++
            }
        } (),
        _getFileSize: function(e) {
            return this._supportHTML5 ? e.fileSize != null ? e.fileSize: e.size: null
        },
        _getFileName: function(e) {
            return this._supportHTML5 ? e.fileName != null ? e.fileName: e.name: e.value.replace(/.*(\/|\\)/, "")
        },
        _getFileExtension: function(e) {
            var t = this._getFileName(e);
            return t.split(".").pop().toLowerCase()
        },
        _supportHTML5: window.File && window.FileList
    });
    if(!$.exts) {
      $.exts = {};
    }
    $.extend($.exts, {
        upload: function(e, t) {
            return new Upload(e, t)
        }
    })
    /*
    if(!window.ace){
      window.ace = {};
    }
    $.extend(ace, {
      upload: function(e, t) {
          return new Upload(e, t)
      }
  })
  */
}(jQuery);